home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1998 January: Mac OS SDK / Dev.CD Jan 98 SDK2.toast / Development Kits (Disc 2) / QuickTime / Sample Code / QT Sound Clock / SoundClock.c next >
Encoding:
C/C++ Source or Header  |  1997-02-26  |  8.7 KB  |  314 lines  |  [TEXT/MPS ]

  1. #include <Resources.h>
  2. #include <Sound.h>
  3. #include <SoundInput.h>
  4. #include <TextUtils.h>
  5.  
  6. #include "ClockComponent.h"
  7. #include "MicroSeconds.h"
  8.  
  9. /* Our version of a Sound Manager 3.1 */
  10. /*    the one in Sound.h returns a nasty struct which is really a long */
  11. extern pascal long rSndSoundManagerVersion(void)
  12.     FOURWORDINLINE(0x203c, 0x000c, 0x0008, 0xa800);
  13.  
  14. pascal ComponentResult SoundClockComponent(ComponentParameters *tp,Handle s);
  15.  
  16. typedef struct {
  17.     unsigned long                ticks;
  18.     unsigned long                lastMicroSeconds;
  19.     SndChannelPtr                channel;
  20.     ExtSoundHeader                 header;
  21.     unsigned short                shortSampleRate;
  22.     Component                    capturedClock;
  23. } SoundClockSharedGlobalsRecord, *SoundClockSharedGlobals;
  24.  
  25. typedef struct {
  26.     ComponentInstance            delegateComponent;
  27.     ComponentInstance            self;
  28.     SoundClockSharedGlobals        sharedGlobals;
  29. } SoundClockGlobalsRecord, *SoundClockGlobals;
  30.  
  31. #define  DEFINE_CLOCK_COMPONENT
  32.     #define cnames(a) SoundClock##a
  33.     #define compID  SoundClockGlobals store
  34.     #define clockCallBackType void *
  35.     #include "ClockComponent.h"
  36.  
  37. #define kSoundClockVersion 0x00010004
  38.  
  39. OSErr primeCallBack(SoundClockSharedGlobals sharedGlobals);
  40. pascal void soundClockCompletionRoutine(SndChannelPtr chan, SndCommand *cmd);
  41.  
  42. #if !INITBUILD
  43.     ComponentFunctionUPP SoundClockSelectorLookup( short selector );
  44.     pascal ComponentResult SoundClockComponent( ComponentParameters *params, Handle storage );
  45.  
  46.     pascal ComponentResult SoundClockComponent( ComponentParameters *params, Handle storage )
  47.     {
  48.         ComponentFunctionUPP    componentProc = 0;
  49.         ComponentResult retstat = 0;
  50.     
  51.         componentProc = SoundClockSelectorLookup( params->what );
  52.             
  53.         if (componentProc)
  54.             retstat = CallComponentFunctionWithStorage(storage, params, componentProc);
  55.         else {
  56.             retstat = DelegateComponentCall(params, **(ComponentInstance **)storage);
  57.             }
  58.     bail:
  59.         return retstat;            /* is this okay? */
  60.     }
  61.     
  62.     ComponentFunctionUPP SoundClockSelectorLookup( short selector )
  63.     {
  64.         ComponentFunctionUPP    componentProc = 0;
  65.     
  66.         #undef ComponentCall
  67.         #define ComponentCall(a)    case kClock##a##Selector: componentProc = (ComponentFunctionUPP)SoundClock##a; break;
  68.         #define ComponentNoError(a)    case kClock##a##Selector: componentProc = (ComponentFunctionUPP)-1; break;
  69.         #define ComponentDelegate(a)
  70.         #define ComponentError(a)
  71.         
  72.         switch (selector) {
  73.             #include "SoundClockDispatch.h"
  74.             }
  75.     
  76.         return componentProc;
  77.     }
  78. #else
  79.     #define SoundClockSelectorLookup COMPONENTSELECTORLOOKUP
  80.     ComponentFunctionUPP SoundClockSelectorLookup( short selector );
  81. #endif
  82.  
  83. pascal ComponentResult SoundClockCanDo(SoundClockGlobals store, short ftnNumber)
  84. {
  85.     ComponentResult result;
  86.  
  87.     result = (SoundClockSelectorLookup( ftnNumber ) != 0);
  88.     if (!result) {
  89.         result = ClockCanDo( store->delegateComponent, ftnNumber );
  90.         }
  91.     return result;
  92. }
  93.  
  94. pascal ComponentResult SoundClockVersion(SoundClockGlobals store)
  95. {
  96. #pragma unused(storage)
  97.  
  98.     return kSoundClockVersion;
  99. }
  100.  
  101. pascal ComponentResult SoundClockOpen( SoundClockGlobals store, ComponentInstance self )
  102. {
  103.     Component callBackClockComponent;
  104.     ComponentResult err = noErr;
  105.     SoundClockSharedGlobals sharedGlobals;
  106.     THz saveZone = GetZone();
  107.  
  108.     if (rSndSoundManagerVersion() < 0x03100000)
  109.         return paramErr;
  110.  
  111.     store = (SoundClockGlobals)NewPtrClear(sizeof(SoundClockGlobalsRecord));
  112.     if (err = MemError()) goto bail;
  113.  
  114.     store->self = self;
  115.     SetComponentInstanceStorage(self, (Handle)store);
  116.  
  117.     sharedGlobals = (SoundClockSharedGlobals)GetComponentRefcon((Component)self);
  118.     if (!sharedGlobals) {
  119.         sharedGlobals = (SoundClockSharedGlobals)NewPtrSysClear(sizeof(SoundClockSharedGlobalsRecord));
  120.         if (err = MemError()) goto bail;
  121.         SetComponentRefcon((Component)self, (long)sharedGlobals);
  122.     }
  123.     store->sharedGlobals = sharedGlobals;
  124.  
  125.     err = SoundClockRegister(store);
  126.     if (err) goto bail;
  127.  
  128.     if (!sharedGlobals->channel) {
  129.         SetZone(SystemZone());
  130.  
  131.         err = SndNewChannel(&sharedGlobals->channel, sampledSynth, 0, soundClockCompletionRoutine);
  132.         if (err) goto bail;
  133.  
  134.         err = SndGetInfo(sharedGlobals->channel, siSampleRate, &sharedGlobals->header.sampleRate);
  135.         if (err) goto bail;
  136.  
  137.         sharedGlobals->shortSampleRate = (unsigned short)(sharedGlobals->header.sampleRate >> 16);
  138.  
  139.         err = SndGetInfo(sharedGlobals->channel, siSampleSize, &sharedGlobals->header.sampleSize);
  140.         if (err) goto bail;
  141.  
  142.         err = SndGetInfo(sharedGlobals->channel, siNumberChannels, &sharedGlobals->header.numChannels);
  143.         if (err) goto bail;
  144.  
  145.         sharedGlobals->header.samplePtr = NewPtrSysClear(1024 * 2 * 2);
  146. //        sharedGlobals->header.numChannels = 2;
  147. //        sharedGlobals->header.sampleRate = rate44khz;
  148.         sharedGlobals->header.loopStart = 0;
  149.         sharedGlobals->header.loopEnd = 0;
  150.         sharedGlobals->header.encode = extSH;
  151.         sharedGlobals->header.baseFrequency = kMiddleC;
  152.         sharedGlobals->header.numFrames = 1024;
  153.         sharedGlobals->header.AIFFSampleRate = 0;
  154.         sharedGlobals->header.markerChunk = nil;
  155.         sharedGlobals->header.instrumentChunks = nil;
  156.         sharedGlobals->header.AESRecording = nil;
  157. //        sharedGlobals->header.sampleSize = 16;
  158.         sharedGlobals->header.futureUse1 = 0;
  159.         sharedGlobals->header.futureUse2 = 0;
  160.         sharedGlobals->header.futureUse3 = 0;
  161.         sharedGlobals->header.futureUse4 = 0;
  162.  
  163.         err = primeCallBack(sharedGlobals);
  164.         if (err) goto bail;
  165.     }
  166.  
  167.     store->delegateComponent = OpenComponent(store->sharedGlobals->capturedClock);
  168.     if (!store->delegateComponent) {
  169.         err = cantOpenHandler;
  170.         goto bail;
  171.     }
  172.             
  173. bail:
  174.     SetZone(saveZone);
  175.  
  176.     return err;
  177. }
  178.  
  179. pascal ComponentResult SoundClockClose( SoundClockGlobals store, ComponentInstance self )
  180. {
  181. #pragma unused(self)
  182.     if (store) {
  183.         if (CountComponentInstances((Component)self) == 1) {
  184.             SoundClockSharedGlobals sharedGlobals = store->sharedGlobals;
  185.  
  186.             if (sharedGlobals) {
  187.                 if (sharedGlobals->channel) {
  188.                     SndDisposeChannel(sharedGlobals->channel, true);
  189.                     sharedGlobals->channel = nil;
  190.                 }
  191.                 if (sharedGlobals->header.samplePtr) {
  192.                     DisposePtr(sharedGlobals->header.samplePtr);
  193.                     sharedGlobals->header.samplePtr = nil;
  194.                 }
  195.             }
  196.         }
  197.         CloseComponent(store->delegateComponent);
  198.         DisposePtr((Ptr)store);
  199.     }
  200.  
  201.     return noErr;
  202. }
  203.  
  204. pascal ComponentResult SoundClockRegister (SoundClockGlobals store)
  205. {
  206.     ComponentDescription someComponent;
  207.     Component callBackClockComponent;
  208.     OSErr err;
  209.  
  210.     if (store->sharedGlobals == nil)
  211.         return paramErr;
  212.  
  213.     if (store->sharedGlobals->capturedClock)
  214.         return noErr;
  215.  
  216.     someComponent.componentType = clockComponentType;
  217.     someComponent.componentSubType = 0;
  218.     someComponent.componentManufacturer = 'appl';
  219.     someComponent.componentFlags = kClockRateIsLinear | kClockImplementsCallBacks;
  220.     someComponent.componentFlagsMask = someComponent.componentFlags;
  221.     callBackClockComponent = FindNextComponent(0, &someComponent);
  222.     if (!callBackClockComponent) {
  223.         err = cantFindHandler;
  224.         goto bail;
  225.     }
  226.  
  227.     store->sharedGlobals->capturedClock = CaptureComponent(callBackClockComponent, (Component)store->self);
  228.     if (store->sharedGlobals->capturedClock == nil)
  229.         return cantOpenHandler;
  230.  
  231. bail:
  232.     return err;
  233. }
  234.  
  235. pascal ComponentResult SoundClockUnregister (SoundClockGlobals store)
  236. {
  237.     if (store->sharedGlobals == nil)
  238.         return paramErr;
  239.  
  240.     if (store->sharedGlobals->capturedClock)
  241.         UncaptureComponent(store->sharedGlobals->capturedClock);
  242.  
  243.     return noErr;
  244. }
  245.  
  246. pascal ComponentResult SoundClockGetTime( SoundClockGlobals store, register TimeRecord *theTime)
  247. {
  248. #pragma unused(store)
  249.  
  250.     theTime->value.lo = UnsignedFixedMulDiv(store->sharedGlobals->ticks, 1000000, store->sharedGlobals->shortSampleRate);
  251.     theTime->value.lo += (unsigned long)MicroSeconds() - store->sharedGlobals->lastMicroSeconds;
  252.     theTime->value.hi = 0;
  253.     theTime->scale = 1000000;
  254.  
  255.     return(noErr);
  256. }
  257.  
  258. OSErr primeCallBack(SoundClockSharedGlobals sharedGlobals)
  259. {
  260.     OSErr err;
  261.     SndCommand cmd;
  262.  
  263.     cmd.cmd = bufferCmd;
  264.     cmd.param1 = 0;
  265.     cmd.param2 = (long) &sharedGlobals->header;
  266.     err = SndDoImmediate(sharedGlobals->channel, &cmd);
  267.     if (err) goto bail;
  268.  
  269.     cmd.cmd = callBackCmd;
  270.     cmd.param1 = 0;
  271.     cmd.param2 = (long)sharedGlobals;
  272.     err = SndDoCommand(sharedGlobals->channel, &cmd, true);        /* tell me when it's done */
  273.     if (err) goto bail;
  274.  
  275. bail:
  276.     return err;
  277. }
  278.  
  279. pascal void soundClockCompletionRoutine(SndChannelPtr chan, SndCommand *cmd)
  280. {
  281.     SoundClockSharedGlobals sharedGlobals = (SoundClockSharedGlobals)cmd->param2;
  282.  
  283.     sharedGlobals->ticks += 1024;
  284.     sharedGlobals->lastMicroSeconds = MicroSeconds();
  285.  
  286.     primeCallBack(sharedGlobals);
  287. }
  288.  
  289.  
  290. #if !INITBUILD
  291.  
  292. Component RegisterSoundClockComponent(void);
  293. Component RegisterSoundClockComponent()
  294.     {
  295.     ComponentDescription someComponent;
  296.     register Component systemClockComponent;
  297.  
  298.     someComponent.componentType = clockComponentType;
  299.     someComponent.componentManufacturer = 'appl';
  300.     someComponent.componentFlags = 3;
  301.     someComponent.componentFlagsMask = 0;
  302. //    someComponent.componentSubType = systemSoundClock;
  303.  
  304.     systemClockComponent = RegisterComponent(&someComponent, (void *)SoundClockComponent,1,0,0,0);
  305.     SetDefaultComponent( systemClockComponent, 7 );
  306.     
  307.     return systemClockComponent;
  308.     }
  309.  
  310.  
  311. #endif
  312.  
  313.  
  314.